import random
import re
import json
import requests
import os

# path 指定下载路径
path = r"F:\Videos\BiliBili"

class BiLiBiLi():
    def __init__(self, uid):
        """
        uid  Bilbili用户的UID
        :param uid:
        """
        self.uid = str(uid)
        self.ps = 30
        self.tid = 0
        self.pn = 1
        self.header = {
            'Range': 'bytes=0-',
            'referer': "",
            'origin': 'https://www.bilibili.com/',
            # 'cookie':'填写自己的B站大会员cookie',
            'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36 Edg/85.0.564.63'
        }
        self.count = 0
        self.total = 0

    def BL_get_all(self,has_choose=False):
        url = f"https://api.bilibili.com/x/space/arc/search?mid={self.uid}&ps={self.ps}&tid={self.tid}&pn={self.pn}&keyword=&order=pubdate&jsonp=jsonp"
        self.header['referer'] = url
        result = requests.get(url, headers=self.header).json()
        if not has_choose:
            print(f"result:{result}")
            print("此用户共有以下视频分类:")
            for item in result["data"]["list"]["tlist"].values():
                print(f"{item}")
                print(f"{item['tid']}:{item['name']},视频数量{item['count']}个")
            print(f"0:所有视频,共{result['data']['page']['count']}个")
            choice = input("请输入选择：")
            if choice == '0':
                print("你选择了视频分类：全部视频")
                self.total = result['data']['page']['count']
                self.download_all(result)
            else:
                print(f"你选择了视频分类:{result['data']['list']['tlist'][choice]['name']}")
                self.tid = choice
                self.BL_get_all(True)
        else:
            self.total = result['data']['page']['count']
            self.download_all(result)

    def download_all(self, response_json_data):
        for item in response_json_data["data"]["list"]["vlist"]:
            self.count += 1
            print(f"总共需要下载{self.total}个视频,正在下载第{self.count}个视频:{item['title']}")
            url = f"https://www.bilibili.com/video/{item['bvid']}"
            self.BL_download(url, item["title"])
        if len(response_json_data["data"]["list"]["vlist"]) == self.ps:
            self.pn += 1
            self.BL_get_all(True)

    def BL_download(self, url, title):
        self.header['referer'] = url
        html = requests.get(url, headers=self.header).text
        json_data = re.findall('window.__playinfo__=(.*?)</script>', html)[0]
        # video_name = re.findall(',"title":"(.*?)","', html)[0]
        # if video_name == '':
        #     video_name = int(random.random() * 2 * 1000)
        # if len(str(video_name)) > 20:
        #   video_name = video_name[:20]
        video_dir = os.path.join(path,self.uid, title)
        os.makedirs(video_dir)
        video = json.loads(json_data)['data']['dash']['video'][0]['baseUrl']
        self.download(video, os.path.join(video_dir, title + '.flv'))
        print("【BiLiBiLi】: {} 视频下载完成！".format(title))
        audio = json.loads(json_data)['data']['dash']['audio'][0]['baseUrl']
        self.download(audio, os.path.join(video_dir, title + '.mp3'))
        print("【BiLiBiLi】: {} 音频下载完成！".format(title))

    def download(self, url, rel_path):
        r = requests.get(url, headers=self.header)
        with open(rel_path, 'wb')as f:
            f.write(r.content)

def user_ui():
    print('*' * 10 + '\t BiLiBiLi视频下载\t' + '*' * 10)
    share_url = input('请输入用户UID: ')
    BiLiBiLi(share_url).BL_get_all()



if __name__ == '__main__':
    user_ui()
